// service/TravelRouterService.ts
/*
    a. 参数为一个顾客的customerName
    b. 先检查该顾客是否存在. 若存在, 查询该用户的预约信息, 获取预约信息ReservationKey(格式为"reservationType-reservationMessage-customerName")
    c. 获取ReservationKey的reservationMessage;
    d. 创建一个RoutePoint集合, 用于存储路径信息.
        e. 对于Bus和Hotel的预约信息, reservationMessage为Bus和Hotel的Location值, 先检查RouterPoint集合中是否存在同样location的RoutePoint对象, 若存在则更新其isHotelReserved或isBusReserved值为true, 若不存在, 则直接添加一个isHotelReserved或isBusReserved值为true的RoutePoint对象
    f. 创建一个RouteTransport数组
    g. 对于Flight的预约信息, reservationMessage为FlightNum, 通过FlightNum查询航班的出发城市和到达城市, 将每趟航班的出发城市和到达城市添加到RouteTransport数组中, 同时将航班的出发城市和到达城市作为loaction添加到RoutePoint集合(如果RoutePoint中不存在有相同Location值的对象
    h. 最后返回值为包含 RoutePoint集合和RouteTransport数组的一个对象
*/
import { CustomerService, ReservationService } from "../../service";
import { FlightService } from "../../service";
import type { RoutePoint, RouteTransport } from "../../types/DataTypes";

export class TravelRouteService {
    // ==================== 旅行路线查询 ====================
    
    /**
     * 查询顾客的旅行路线
     * @param customerName 顾客姓名
     * @returns 包含RoutePoint集合和RouteTransport数组的对象
     */
    static async getCustomerTravelRoute(customerName: string): Promise<{
        routePoints: RoutePoint[];
        routeTransports: RouteTransport[];
    }> {
        try {
            // 1. 检查顾客是否存在
            await this.checkCustomerExists(customerName);
            
            // 2. 获取顾客的预约信息
            const reservations = await this.getCustomerReservations(customerName);
            
            // 3. 处理预约信息，构建旅行路线
            const routePoints: RoutePoint[] = [];
            const routeTransports: RouteTransport[] = [];
            
            for (const reservation of reservations) {
                await this.processReservation(
                    reservation,
                    routePoints,
                    routeTransports
                );
            }

            if (routePoints.length < 1) {
                throw new Error('未查询到旅游路线')
            }
            
            return {
                routePoints,
                routeTransports
            };
        } catch (error) {
            throw error;
        }
    }
    
    /**
     * 检查顾客是否存在
     * @param customerName 顾客姓名
     */
    private static async checkCustomerExists(customerName: string): Promise<void> {
        const exists = await CustomerService.customerNameExists(customerName);
        if (!exists) {
            throw new Error(`顾客不存在: ${customerName}`);
        }
    }
    
    /**
     * 获取顾客的预约信息
     * @param customerName 顾客姓名
     * @returns 预约信息数组
     */
    private static async getCustomerReservations(customerName: string) {
        return await ReservationService.searchReservations({
            customerName
        });
    }
    
    /**
     * 处理单个预约信息
     * @param reservation 预约信息
     * @param routePoints RoutePoint集合
     * @param routeTransports RouteTransport数组
     */
    private static async processReservation(
        reservation: any,
        routePoints: RoutePoint[],
        routeTransports: RouteTransport[]
    ): Promise<void> {
        const { reservationType, reservationKey } = reservation;
        
        // 解析reservationKey获取reservationMessage
        const parts = reservationKey.split('-');
        if (parts.length < 3) {
            console.warn(`无效的reservationKey格式: ${reservationKey}`);
            return;
        }
        
        const reservationMessage = parts[1];
        
        switch (reservationType) {
            case 1: // 航班
                await this.processFlightReservation(
                    reservationMessage,
                    routePoints,
                    routeTransports
                );
                break;
            case 2: // 巴士
                this.processBusReservation(reservationMessage, routePoints);
                break;
            case 3: // 酒店
                this.processHotelReservation(reservationMessage, routePoints);
                break;
            default:
                console.warn(`未知的预约类型: ${reservationType}`);
        }
    }
    
    /**
     * 处理航班预约
     * @param flightNum 航班号
     * @param routePoints RoutePoint集合
     * @param routeTransports RouteTransport数组
     */
    private static async processFlightReservation(
        flightNum: string,
        routePoints: RoutePoint[],
        routeTransports: RouteTransport[]
    ): Promise<void> {
        try {
            // 获取航班信息
            const flight = await FlightService.getFlightByFlightNum(flightNum);
            if (!flight) {
                console.warn(`航班不存在: ${flightNum}`);
                return;
            }
            
            const { fromCity, arivCity } = flight;
            
            // 添加到RouteTransport
            routeTransports.push({
                fromCity,
                arivCity
            });
            
            // 确保出发城市和到达城市都在RoutePoint中
            this.ensureLocationInRoutePoints(fromCity, routePoints);
            this.ensureLocationInRoutePoints(arivCity, routePoints);
            
        } catch (error) {
            console.error(`处理航班预约失败: ${flightNum}`, error);
        }
    }
    
    /**
     * 处理酒店预约
     * @param location 酒店位置
     * @param routePoints RoutePoint集合
     */
    private static processHotelReservation(
        location: string,
        routePoints: RoutePoint[]
    ): void {
        const existingPoint = routePoints.find(point => point.location === location);
        
        if (existingPoint) {
            // 更新已存在的RoutePoint
            existingPoint.isHotelReserved = true;
        } else {
            // 创建新的RoutePoint
            routePoints.push({
                location,
                isBusReserved: false,
                isHotelReserved: true
            });
        }
    }
    
    /**
     * 处理巴士预约
     * @param location 巴士位置
     * @param routePoints RoutePoint集合
     */
    private static processBusReservation(
        location: string,
        routePoints: RoutePoint[]
    ): void {
        const existingPoint = routePoints.find(point => point.location === location);
        
        if (existingPoint) {
            // 更新已存在的RoutePoint
            existingPoint.isBusReserved = true;
        } else {
            // 创建新的RoutePoint
            routePoints.push({
                location,
                isBusReserved: true,
                isHotelReserved: false
            });
        }
    }
    
    /**
     * 确保位置在RoutePoint集合中
     * @param location 位置
     * @param routePoints RoutePoint集合
     */
    private static ensureLocationInRoutePoints(
        location: string,
        routePoints: RoutePoint[]
    ): void {
        const exists = routePoints.some(point => point.location === location);
        if (!exists) {
            routePoints.push({
                location,
                isBusReserved: false,
                isHotelReserved: false
            });
        }
    }
}